package com.loy.config;

import com.loy.handler.MyAuthenticationFailHandler;
import com.loy.handler.MyAuthenticationSuccessHandler;
import com.loy.handler.MyLogoutSuccessHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;

/**
 * 1. 这个类 WebSecurityConfig 继承了 WebSecurityConfigurerAdapter 这个类
 *    就打破了security 使用默认的 请求校验方式，
 *    我们重写了 configure(HttpSecurity http)  方法之后，之后所有的请求就会根据我们重写的方式进行认证
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .mvcMatchers("/index","/login").permitAll()  // 这里写要放行的请求路径，
                .anyRequest().authenticated()// 这里表示其他任何请求都需要认证
                .and()
                .formLogin() // 这里表示 除了 /index 路径之外的其他任何请求，都需要使用表单认证
                .loginPage("/login")// 加上这个之后，就表示使用了我们自定义的登录界面,如果没有登陆的话，那么会重定向到这个路径，【注意】：一旦我们指定了自定义的登录界面之后，必须指定登录的url
                .loginProcessingUrl("/doLogin") // 指定登录的url
//                .successForwardUrl("/hello") //账号密码 认证成功，要跳转到哪个路径，转原理是 转发
//                .defaultSuccessUrl("") // 账号密码 认证成功之后，要跳转到哪个路径，原理是重定向
                .successHandler(new MyAuthenticationSuccessHandler()) // 账号密码认证成功之后的处理，主要用于 前后端分离开发过程中
//                .failureForwardUrl("/login") // 账号密码 认证失败之后 的路径跳转
                .failureHandler(new MyAuthenticationFailHandler()) // 自定义认证失败之后的处理，主要用于前后端分离开发中
                .and()
                .logout()// 注销登录，就是
                .logoutUrl("/logout") // 指定退出登录的url，不写这一句的时候，默认也是这个路径，但是只有是GET请求的时候，才会执行退出
//                .logoutRequestMatcher(new OrRequestMatcher(  // 上面那一种 .logoutUrl("/logout")  是拦截GET 退出登录请求之后，才执行退出，但是针对其他请求方式的退出，例如POST的话，是不起作用的
//                                                            //  使用这个 .logoutRequestMatcher 之后，可以匹配多个退出登录的请求路径，以及请求的方式
//                        new AntPathRequestMatcher("/aa","GET"),
//                        new AntPathRequestMatcher("/bb","POST")
//
//                ))
                .clearAuthentication(true) // 注销登录之后，清楚认证信息
                .invalidateHttpSession(true)// 注销登录之后，清除session数据
//                .logoutSuccessUrl("/login")// 注销登录之后，设置跳转路径
                .logoutSuccessHandler(new MyLogoutSuccessHandler()) // 在前后端分离的场景中，使用这个，来实现注销成功之后的处理
                .and()
                .csrf().disable(); // 先关闭 csrf 跨站请求保护
    }
}
